import { changeRecords } from '@/components/Common/ExecutorShowComp';
import EntityIcon from '@/components/Common/GlobalComps/entityIcon';
import FormItem from '@/components/DataStandard/WorkForm/Viewer/formItem';
import { command, model, schema } from '@/ts/base';
import { IWorkTask, TaskStatus } from '@/ts/core';
import { IExecutor } from '@/ts/core/work/executor';
import { ReceptionChange } from '@/ts/core/work/executor/reception';
import { AddNodeType, convertToFields, getNodeByNodeId } from '@/utils/work';
import ProTable from '@ant-design/pro-table';
import { Button, Card, Input, Modal, Space, message } from 'antd';
import React, { ReactNode, useState } from 'react';

export interface TaskDetailType {
  task: IWorkTask;
  finished: () => void;
  fromData?: Map<string, model.FormEditData>;
}

export interface ConfirmProps {
  task: IWorkTask;
  executor: IExecutor;
}

const TaskApproval: React.FC<TaskDetailType> = ({ task, finished, fromData }) => {
  if (task.isHistory) {
    return <></>;
  }
  const [open, setOpen] = React.useState<boolean>(false);
  const [comment, setComment] = useState<string>('');
  const [confirm, setConfirm] = useState(<></>);
  const gatewayData = new Map<string, string[]>();
  const [nextNodes, setNextNodes] = useState<schema.XWorkNode[]>([]);
  // 审批
  const approvalTask = async (status: number) => {
    await task.approvalTask(status, comment, fromData, gatewayData);
    if (status == TaskStatus.RefuseStart) {
      if (task.instanceData?.reception) {
        const executor = new ReceptionChange(
          {
            id: '',
            funcName: '任务状态变更',
            trigger: '',
          },
          task,
        );
        await executor.reject();
      }
    }
    command.emitter('preview', 'work');
    setComment('');
    finished();
  };

  const validation = (): boolean => {
    if (task.instanceData && fromData) {
      const valueIsNull = (value: any) => {
        return (
          value === null ||
          value === undefined ||
          (typeof value === 'string' && value.length < 1)
        );
      };
      for (const formId of fromData.keys()) {
        const data: any = fromData.get(formId)?.after.at(-1) ?? {};
        for (const item of task.instanceData.fields[formId]) {
          const isRequired = task.instanceData.data[formId]
            .at(-1)
            ?.rules?.find(
              (i) => i.destId === item.id && i.typeName === 'isRequired',
            )?.value;
          if (
            (isRequired == undefined || isRequired == true) &&
            item.options?.isRequired &&
            valueIsNull(data[item.id])
          ) {
            return false;
          }
        }
      }
    }
    return true;
  };

  const approving = async () => {
    if (validation()) {
      if (['事项'].includes(task.taskdata.taskType)) {
        const res = await task.loadNextNodes();
        if (res.success) {
          if (res.data?.result) {
            const customNodes = res.data.result.filter(
              (a) => a.nodeType === AddNodeType.CUSTOM,
            );
            if (customNodes.length > 0) {
              setOpen(true);
              setNextNodes(customNodes);
              return;
            }
          }
        } else {
          message.warn('查询下一节点异常!');
          return;
        }
      }
      await approvalTask(TaskStatus.ApprovalStart);
    } else {
      message.warn('请完善表单内容再提交!');
    }
  };

  const Confirm: React.FC<ConfirmProps> = (props) => {
    const [open, setOpen] = useState(true);

    let content: ReactNode = null;
    let title = '字段变更确认';

    if (props.executor.metadata.funcName == '字段变更') {
      content = (
        <Space style={{ width: '100%' }} direction="vertical">
          <span>确认后，您的数据将自动产生变更操作，变更字段如下</span>
          {props.executor.metadata.changes.map((item, index) => {
            item.fieldChanges.forEach((change) => {
              switch (change.options?.defaultType) {
                case 'currentPeriod':
                  change.after = task.belong.financial.current;
                  break;
              }
            });
            return (
              <Card key={index} title={item.name}>
                <ProTable
                  key={'id'}
                  search={false}
                  options={false}
                  tableAlertRender={false}
                  dataSource={item.fieldChanges}
                  columns={changeRecords}
                />
              </Card>
            );
          })}
        </Space>
      );
    } else if (props.executor.metadata.funcName == '任务状态变更') {
      if (!task.instanceData?.reception) {
        message.warning('未找到任务接收信息，该办事需要从任务接收中发起提交！');
        return;
      }

      content = (
        <Space style={{ width: '100%' }} direction="vertical">
          <div>
            <span>确认后，将会将任务 </span>
            <EntityIcon entity={task.instanceData.reception} showName />
            <span>{task.instanceData.reception.period}</span>
            <span>状态变更为已完成</span>
          </div>
        </Space>
      );
    } else {
      return <></>;
    }

    return (
      <Modal
        open={open}
        title={title}
        width={1200}
        onOk={async () => {
          try {
            await props.executor.execute(fromData ?? new Map());
            await approving();
            setOpen(false);
          } catch (error) {
            message.error((error as Error).message);
          }
        }}
        onCancel={() => {
          setOpen(false);
        }}>
        {content}
      </Modal>
    );
  };

  if (task.taskdata.status >= TaskStatus.ApprovalStart) {
    return <></>;
  }
  return (
    <>
      <Modal
        width={400}
        title="请选择审批人"
        open={open}
        onOk={async () => {
          setOpen(false);
          await approvalTask(TaskStatus.ApprovalStart);
        }}
        onCancel={() => setOpen(false)}>
        {nextNodes
          .map((a) => convertToFields(a, task.belong))
          .map((field) => (
            <FormItem
              rules={[]}
              key={field.id}
              data={gatewayData}
              numStr={'1'}
              field={field}
              belong={task.belong}
              onValuesChange={(field, data) => {
                gatewayData.set(field, Array.isArray(data) ? data : [data]);
              }}
            />
          ))}
      </Modal>
      <div style={{ padding: 10, display: 'flex', alignItems: 'flex-end', gap: 10 }}>
        <Input.TextArea
          style={{ height: 100, width: 'calc(100% - 80px)' }}
          placeholder="请填写备注信息"
          onChange={(e) => {
            setComment(e.target.value);
          }}
        />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <Button
            type="primary"
            onClick={() => {
              const node = getNodeByNodeId(task.taskdata.nodeId, task.instanceData?.node);
              const executors = node ? task.loadExecutors(node) : [];
              const executor = executors.find(
                (item) =>
                  item.metadata.funcName == '字段变更' ||
                  item.metadata.funcName == '任务状态变更',
              );
              if (executor) {
                setConfirm(<Confirm task={task} executor={executor} />);
                return;
              }
              approving();
            }}>
            通过
          </Button>

          {/* 归档节点驳回会导致流程实例消失 */}
          {task.taskdata.approveType != AddNodeType.END && (
            <Button
              type="primary"
              danger
              onClick={() => approvalTask(TaskStatus.RefuseStart)}>
              驳回
            </Button>
          )}
        </div>
        {confirm}
      </div>
    </>
  );
};

export default TaskApproval;
